#include<stdio.h>
#include<malloc.h>
#define MAX 100  //多项式最多项数
typedef struct
{
	double coef; //系数
	int exp; //指数
}PolyArray; //存放多项式的数组类型

typedef struct pnode
{
	double coef; //系数
	int exp; //指数
	struct pnode* next;
}PolyNode; //声明多项式单链表结点类型

void CreatePolyR(PolyNode*& L, PolyArray a[], int n) //尾插法建表
{
	PolyNode* s, * r;
	int i;
	L = (PolyNode*)malloc(sizeof(PolyNode));
	L->next = NULL;
	r = L; //r始终指向尾结点，开始时指向头结点
	for (i = 0; i < n; i++)
	{
		s = (PolyNode*)malloc(sizeof(PolyNode)); //创建新结点
		s->coef = a[i].coef;
		s->exp = a[i].exp;
		r->next = s; //将结点s插入到结点r之后
		r = s;
	}
	r->next = NULL; //尾结点next域置为NULL
}

void DispPoly(PolyNode* L) //输出多项式单链表
{
	PolyNode* p = L->next;
	while (p != NULL)
	{
		if (p->coef > 0) printf("+");//系数为正，用+连接	
		if (p->exp == 0) printf("%g", p->coef); //指数为0，只输出系数
		else if (p->exp == 1) printf("%gx", p->coef); //指数为1
		else printf("%gx^%d", p->coef, p->exp); //指数不为1
		p = p->next;
	}
	printf("\n");
}

void DestoryPoly(PolyNode*& L) //销毁多项式单链表
{
	PolyNode* pre = L, * p = pre->next;
	while (p != NULL)
	{
		free(pre);
		pre = p;
		p = pre->next;
	}
	free(pre);
}

void Sort(PolyNode*& L) //将多项式单链表按指数递减排序
{
	PolyNode* p = L->next, * pre, * q;
	if (p != NULL) //L有一个或以上的数据结点
	{
		q = p->next; //q保存p结点的后继节点
		p->next = NULL; //构造只含一个数据结点的有序表
		p = q;
		while (p != NULL) //扫描原L中余下的数据结点
		{
			q = p->next; //q保存p结点的后继节点
			pre = L;
			while (pre->next != NULL && pre->next->exp > p->exp)
				pre = pre->next; //在有序表中找插入节点p的前驱结点pre
			p->next = pre->next; //将结点p插入到结点pre之后
			pre->next = p;
			p = q; //扫描原单链表余下的结点
		}
	}
}

void Add(PolyNode* ha, PolyNode* hb, PolyNode*& hc)  //ha和hb相加得到hc
{
	PolyNode* pa = ha->next, * pb = hb->next, * s, * r;
	double c;
	hc = (PolyNode*)malloc(sizeof(PolyNode));
	r = hc; //r指向尾结点，初始时指向头结点
	while (pa != NULL && pb != NULL) //pa、pb均没有扫描完
	{
		if (pa->exp > pb->exp) //将指数较大的pa结点复制到hc中
		{
			s = (PolyNode*)malloc(sizeof(PolyNode));
			s->exp = pa->exp;
			s->coef = pa->coef;
			r->next = s;
			r = s;
			pa = pa->next;
		}
		else if(pa->exp < pb->exp) //将指数较大的pb结点复制到hc中
		{
			s = (PolyNode*)malloc(sizeof(PolyNode));
			s->exp = pb->exp;
			s->coef = pb->coef;
			r->next = s;
			r = s;
			pb = pb->next;
		}
		else //pa、pb结点的指数相等时
		{
			c = pa->coef + pb->coef; //求两个结点的系数和c
			if (c != 0) //若系数和不为0时创建新结点
			{
				s = (PolyNode*)malloc(sizeof(PolyNode)); 
				s->exp = pa->exp;
				s->coef = c;
				r->next = s;
				r = s;
			}
			pa = pa->next; //pa后移一个结点
			pb = pb->next; //pb后移一个结点
		}
	}
	if (pb != NULL) pa = pb; //复制余下的结点
	while (pa != NULL)
	{
		s = (PolyNode*)malloc(sizeof(PolyNode));
		s->exp = pa->exp;
		s->coef = pa->coef;
		r->next = s;
		r = s;
		pa = pa->next;
	}
	r->next = NULL; //尾结点next设置为空
}

void Sub(PolyNode* ha, PolyNode* hb, PolyNode*& hd)  //ha和hb相加得到hc
{
	PolyNode* pa = ha->next, * pb = hb->next, * s, * r;
	double c;
	hd = (PolyNode*)malloc(sizeof(PolyNode));
	r = hd; //r指向尾结点，初始时指向头结点
	while (pa != NULL && pb != NULL) //pa、pb均没有扫描完
	{
		if (pa->exp > pb->exp) //将指数较大的pa结点复制到hc中
		{
			s = (PolyNode*)malloc(sizeof(PolyNode));
			s->exp = pa->exp;
			s->coef = pa->coef;
			r->next = s;
			r = s;
			pa = pa->next;
		}
		else if (pa->exp < pb->exp) //将指数较大的pb结点复制到hc中
		{
			s = (PolyNode*)malloc(sizeof(PolyNode));
			s->exp = pb->exp;
			s->coef = 0-pb->coef;
			r->next = s;
			r = s;
			pb = pb->next;
		}
		else //pa、pb结点的指数相等时
		{
			c = pa->coef - pb->coef; //求两个结点的系数和c
			if (c != 0) //若系数相减不为0时创建新结点
			{
				s = (PolyNode*)malloc(sizeof(PolyNode));
				s->exp = pa->exp;
				s->coef = c;
				r->next = s;
				r = s;
			}
			pa = pa->next; //pa后移一个结点
			pb = pb->next; //pb后移一个结点
		}
	}
	if (pb != NULL) pa = pb; //复制余下的结点
	while (pa != NULL)
	{
		s = (PolyNode*)malloc(sizeof(PolyNode));
		s->exp = pa->exp;
		s->coef = pa->coef;
		r->next = s;
		r = s;
		pa = pa->next;
	}
	r->next = NULL; //尾结点next设置为空
}

int main()
{
	PolyNode* ha, * hb, * hc, * hd;
	PolyArray a[] = { {3,1},{2,0},{1,3},{4,4} };
	PolyArray b[] = { {3,4},{2,3},{1,0},{5,2},{ 3,6} };
	CreatePolyR(ha, a, 4);
	CreatePolyR(hb, b, 5);
	printf("原多项式A：");
	DispPoly(ha);
	printf("\n");
	printf("原多项式B：");
	DispPoly(hb);
	printf("\n");
	Sort(ha);
	Sort(hb);
	printf("有序多项式A：");
	DispPoly(ha);
	printf("\n");
	printf("有序多项式B：");
	DispPoly(hb);
	printf("\n");

	Add(ha, hb, hc);
	printf("多项式相加：");
	DispPoly(hc);
	printf("\n");

	Sub(ha, hb, hd);
	printf("多项式相减：");
	DispPoly(hd);
	printf("\n");
	/*DestoryPoly(ha);
	DestoryPoly(hb);
	DestoryPoly(hc);*/
	return 0;
}
